<template>
  <el-form label-width="100px" ref="ruleFormRef" :model="spuInfo" :rules="spuRules">
    <el-form-item label="SPU名称" prop="spuName">
      <el-input v-model="spuInfo.spuName" placeholder="SPU名称"></el-input>
    </el-form-item>
    <el-form-item label="SPU品牌" prop="tmId">
      <el-select placeholder="请选择" v-model="spuInfo.tmId">
        <el-option
          :label="tm.tmName"
          :key="tm.id"
          v-for="tm in trademarkList"
          :value="tm.id"
        />
      </el-select>
    </el-form-item>
    <el-form-item label="SPU描述" prop="description">
      <el-input v-model="spuInfo.description" type="textarea" :rows="3" placeholder="SPU描述"></el-input>
    </el-form-item>
    <el-form-item label="SPU图片" prop="spuImageList">
      <el-upload
        v-model:file-list="spuInfo.spuImageList"
        :action="`${BASE_URL}/admin/product/fileUpload`"
        list-type="picture-card"
        :on-preview="handlePictureCardPreview"
        :on-remove="handleRemove"
        :on-success="handleAvatarSuccess"
        :before-upload="beforeAvatarUpload"
      >
        <el-icon>
          <Plus />
        </el-icon>
      </el-upload>

      <el-dialog v-model="dialogVisible">
        <img w-full :src="dialogImageUrl" alt="Preview Image" />
      </el-dialog>
    </el-form-item>
    <el-form-item label="销售属性" prop="spuSaleAttrList">
      <el-select
        v-model="spuInfo.spuSaleAttr"
        :placeholder="`还有${filterBaseSaleAttrList.length}个未选择`"
      >
        <el-option
          :label="bsa.name"
          :key="bsa.id"
          v-for="bsa in filterBaseSaleAttrList"
          :value="bsa.name"
        />
      </el-select>
      <el-button
        :icon="Plus"
        type="primary"
        style="margin-left: 10px"
        @click="addSpuSaleAttr"
        >添加销售属性</el-button
      >
      <el-table border style="margin: 10px 0" :data="spuInfo.spuSaleAttrList">
        <el-table-column
          label="序号"
          type="index"
          align="center"
          width="80px"
        ></el-table-column>
        <el-table-column
          label="属性名"
          prop="saleAttrName"
          width="200px"
        ></el-table-column>
        <el-table-column label="属性值名称列表">
          <template v-slot="{ row, $index }">
            <el-tag
              v-for="tag in row.spuSaleAttrValueList"
              :key="tag"
              class="mx-1"
              closable
              :disable-transitions="false"
              @close="handleClose(tag,row)"
            >
              {{ tag.saleAttrValueName }}
            </el-tag>
            <el-input
              v-if="row.inputVisible"
              ref="InputRef"
              v-model="inputValue"
              class="ml-1 w-20"
              size="small"
              @keyup.enter="handleInputConfirm(row)"
              @blur="handleInputConfirm(row)"
            />
            <el-button
              type="primary"
              :icon="Plus"
              v-else
              class="button-new-tag ml-1"
              size="small"
              @click="showInput(row)"
            >
            </el-button>
          </template>
        </el-table-column>
        <el-table-column label="操作">
          <template v-slot="{row,$index}">
            <el-popconfirm title="确定要删除此属性吗?" @confirm="deleteSaleAttr($index)">
              <template #reference>
                <el-button :icon="Delete" type="danger" size="small"></el-button>
              </template>
            </el-popconfirm>
          </template>
        </el-table-column>
      </el-table>
    </el-form-item>
    <el-form-item>
      <el-button type="primary" @click="submitSpuForm(ruleFormRef)">保存</el-button>
      <el-button @click="emits('changeScene',1)">取消</el-button>
    </el-form-item>
  </el-form>
</template>

<script lang="ts">
export default {
  name: "SpuForm",
};
</script>
<script lang="ts" setup>
import { ref, onMounted, reactive, computed, nextTick } from "vue";
import { Plus } from "@element-plus/icons-vue";
import { ElMessage , ElInput } from "element-plus";
import type {FormInstance, FormRules, UploadProps, UploadUserFile } from "element-plus";
import {
  reqGetTrademarkListData,
  reqGetBaseSaleAttrListData,
  reqSaveSpuInfo,
  reqGetSpuImageList,
  reqGetSpuSaleAttrList,
  reqUpdateSpuInfo
} from "@/api/product/spu";
import { useCategorySelectorInfoStore } from '@/stores/categorySelector';
const formSize = ref('default')
const ruleFormRef = ref<FormInstance>()
const BASE_URL = import.meta.env.VITE_API_URL;
// const props = defineProps(['currentSpuInfo'])
const props = defineProps(['currentSpuInfo', 'aaa', 'bbb'])
// 定义一个SpuInfo对象的数据
const spuInfo = reactive({
  spuName: "", // spu名称
  tmId: "", // 品牌
  description: "", // 品牌描述
  spuImageList: [
    //  "imgName": "string",
    //   "imgUrl": "string",
  ], // 收集的要上传的图片
  spuSaleAttrList: [], // 销售属性
  category3Id: 0, // 三级分类id
  spuSaleAttr: "",
  ...props.currentSpuInfo
});
const inputValue = ref("");
const dialogImageUrl = ref("");
const dialogVisible = ref(false);
const trademarkList = ref([]);
const baseSaleAttrList = ref([]);
const InputRef = ref<InstanceType<typeof ElInput>>();
const emits = defineEmits(['changeScene'])
const categoryStore = useCategorySelectorInfoStore()
// 1. 页面组件挂载完毕后就要发送请求，获取对应的数据
onMounted(async () => {
  // const tradeResult = await reqGetTrademarkListData()
  // const baseSaleResult = await reqGetBaseSaleAttrListData()
  let promies = [reqGetTrademarkListData(), reqGetBaseSaleAttrListData()];
  console.log(spuInfo,spuInfo.id)
  if(spuInfo.id){
    console.log(798416346879465132)
    promies=promies.concat([reqGetSpuImageList(spuInfo.id),reqGetSpuSaleAttrList(spuInfo.id)])
  }
  try {
    // Promise.race()  赛跑形式的请求 谁快就先用谁
    // Promise.allSettled() 允许有失败的请求
    const [responseTrademarkList, responseBaseSaleAttrList,responseSpuImageList, responseSpuSaleAttrList] = 
    await Promise.all(promies)

    // console.log('all',responseTrademarkList,responseBaseSaleAttrList)
    trademarkList.value = responseTrademarkList;
    baseSaleAttrList.value = responseBaseSaleAttrList;
    if(responseSpuImageList&&responseSpuSaleAttrList){
      spuInfo.spuImageList=responseSpuImageList.map(item=>{
        return {
          ...item,
          name:item.imgName,
          url:item.imgUrl
        }
      })
      spuInfo.spuSaleAttrList = responseSpuSaleAttrList
    }
  } catch (error) {
    ElMessage.error("获取品牌数据及销售属性失败...");
  }
});
const addSpuSaleAttr = () => {
  const result =
    spuInfo.spuSaleAttrList.length &&
    spuInfo.spuSaleAttrList.some(
      (item) => item.spuSaleAttrValueList.length === 0
    );
  if (result) {
    ElMessage.error("有属性值为空,请添加.");
    return;
  }
  spuInfo.spuSaleAttrList.push({
    saleAttrName: spuInfo.spuSaleAttr,
    spuSaleAttrValueList: [], // 这个用于收集属性值
  });
  spuInfo.spuSaleAttr = "";
};
// 图片上传相关
// 2. 图片上传之前的格式校验
const beforeAvatarUpload: UploadProps["beforeUpload"] = (rawFile) => {
  const imgArr = ["image/jpeg", "image/png", "image/jpg"];
  if (!imgArr.includes(rawFile.type)) {
    ElMessage.error("图片格式不正确,应该是.jpg/.png/.jpeg等");
    return false;
  } else if (rawFile.size / 1024 / 1024 > 2) {
    ElMessage.error("图片大小不能超过2M,请重新上传...");
    //1T > 1024 G= 1024M > 1024K >1024B
    return false;
  }
  return true;
};
// 3. 上传图片成功后的操作     清除之前的图片校验规则
const handleAvatarSuccess: UploadProps["onSuccess"] = (
  response,
  uploadFile,
  uploadFiles
) => {
  // 一开始上传图片成功的时候，是将图片先上传到服务器端，先存储到服务器中
  // 然后服务器将图片在服务器端的链接地址再响应回浏览器,最后点提交 按钮或是保存的时候，是将图片在服务器端的链接地址和其它相关属性一并再次发送给服务器，最终存储到服务器端的数据库中

  // 解决图片闪动
  // 1. 仍然使用fileList这个变量来渲染照片墙 但是使用spuInfo.spuImageList来收集上传的图片
  // 2. 在渲染照片墙的时候使用spuInfo.spuImageList来渲染 但是需要将v-mode后面的:file-list去掉
  // 3. 使用第3个参数来实现
  console.log(response, uploadFile, uploadFiles);
  // imageUrl.value = URL.createObjectURL(uploadFile.raw!);
  // 重新给照片墙赋值，这种方法可以防止照片抖动
  spuInfo.spuImageList = uploadFiles;
  // spuInfo.spuImageList.push({
  //   // 当前照片墙需要渲染的属性是name和url，而我们发给服务器的数据却是imgName,imgUrl
  //   imgName:uploadFile.name,
  //   imgUrl:response.data || uploadFile.url

  //   // name: uploadFile.name,
  //   // url: response.data || uploadFile.url,
  // });
  // 清除之前的图片校验规则
  ruleFormRef.value?.clearValidate(['spuImageList'])
};

// 4. 删除图片
const handleRemove: UploadProps["onRemove"] = (uploadFile, uploadFiles) => {
  // uploadFile 被删除的那张图片
  // uploadFiles 剩余的未经删除的图片 是一个数组
  // console.log('delImg',uploadFile, uploadFiles);
  spuInfo.spuImageList = uploadFiles;
};
const deleteSaleAttr=(index:number)=>{
  spuInfo.spuSaleAttrList.splice(index,1)
}
// 
const handlePictureCardPreview: UploadProps["onPreview"] = (uploadFile) => {
  dialogImageUrl.value = uploadFile.url!;
  dialogVisible.value = true;
};
// 计算属性获得新的属性列表   过滤之后的列表属性
const filterBaseSaleAttrList = computed(() => {
  return baseSaleAttrList.value.filter((item) => {
    return !spuInfo.spuSaleAttrList.find(
      (obj) => obj.saleAttrName == item.name
    );
  });
});

// el-tag相关
const handleClose = ( tag: string,row) => {
  row.spuSaleAttrValueList.splice(row.spuSaleAttrValueList.indexOf(tag), 1);
};
const showInput = (row) => {
  row.inputVisible = true;
  nextTick(() => {
    InputRef.value!.input!.focus();
  });
};

const handleInputConfirm = (row) => {
  if (inputValue.value) {
    const result = row.spuSaleAttrValueList.some(
      (item) => item.saleAttrValueName === inputValue.value
    );
    if (result) {
      ElMessage.error("此属性已经添加过了,请更换...");
      row.inputVisible = false;
      inputValue.value = "";
      return;
    }
    row.spuSaleAttrValueList.push({
      saleAttrName: row.saleAttrName,
      saleAttrValueName: inputValue.value,
      inputVisible: false,
    });
  }
  row.inputVisible = false;
  inputValue.value = "";
};
// 添加校验规则
const spuRules = reactive<FormRules>({
  spuName: [
    { required: true, message: '请输入spu名称', trigger: 'blur' },
    { min: 1, max: 20, message: '名字长度在1---20之间', trigger: 'blur' }
  ],
  tmId: [
    {
      required: true,
      message: '请选择对应的品牌',
      trigger: 'change'
    }
  ],
  description: [
    {
      required: true,
      message: '请输入spu名称描述',
      trigger: 'blur'
    }
  ],
  spuImageList: [
    {
      type: 'array',
      required: true,
      message: '请至少上传一张图片',
      trigger: 'change',
    },
  ],
  spuSaleAttrList: [
    {
      type: 'array',
      required: true,
      message: '请至少添加一个属性',
      trigger: 'change',
    },
  ],
});
// 提交的校验
const submitSpuForm = async (formEl: FormInstance | undefined) => {
  if (!formEl) return
  await formEl.validate(async(valid, fields) => {
    if (valid) {
      // console.log('submit!')
      // 提交
      const spuSaleAttrList = spuInfo.spuSaleAttrList
      const flag=spuSaleAttrList.length&&spuSaleAttrList.some(item=>item.spuSaleAttrValueList.length===0)
      if(flag) return ElMessage.error('销售属性的属性值有空值,请检查...')
      spuInfo.category3Id=categoryStore.category3Id as number
      spuInfo.spuImageList=spuInfo.spuImageList.map(item=>{
        return{
          imgName:item.name,
          imgUrl:item.response?.data || item.url
        }
      })
      if(spuInfo.id){
        await reqUpdateSpuInfo(spuInfo)
        ElMessage.success("更新成功")
      }else{
        const result = await reqSaveSpuInfo(spuInfo)
        ElMessage.success("添加成功")
      }
      emits('changeScene',1)
    } else {
      console.log('error submit!', fields)
    }
  })
}
</script>
<style></style>
